﻿/**
 * javascript extend.js - javascirpt Object를 확장
 * @name extend.js
 * @overview 
 * @author 손찬욱
 * @version 1.0
 */
/*****************************************************************************/
/*------------------------- String 확장 관련 함수 시작 ----------------------*/
/*****************************************************************************/	
/**
 * javascript String 
 * @name String
 * @constructor
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// is 함수 (Validation)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * @memberOf String
 * @description   값이 null 이거나 white space 문자로만 이루어진 경우 true를 리턴한다.
 * <pre>
 *   "  ".isEmpty();	
 * 위와같이 사용했을 경우 true를 리턴한다.
 * </pre>
 * @return {boolean} true/false
 * @author 손찬욱
 */
String.prototype.isEmpty = function() {
	var tmpStr = this || "";
	tmpStr=tmpStr.trim();
	if(typeof(tmpStr) == "string" && ( tmpStr== "" || tmpStr == "undefined") ) return true;
	else return false;
};

/**
 * @memberOf String
 * @description  숫자만 이루어 져있을 경우 true
 * <pre>
 *
 * </pre>
 * @param  {Char} arguments[0] 제거할문자
 * @return {boolean} true/false
 * @author 손찬욱
 */
String.prototype.isNum = function() {
	return (/^[0-9]+$/).test((this || "").remove(arguments[0])) ? true : false;
};

/**
 * @memberOf String
 * @description  영어만 이루어 져있을 경우 true
 * <pre>
 *
 * </pre>
 * @param  {Char} arguments[0] 제거할문자
 * @return {boolean} true/false
 * @author 손찬욱
 */
String.prototype.isEng = function() {
	return (/^[a-zA-Z]+$/).test((this || "").remove(arguments[0])) ? true : false;
};

/**
 * @memberOf String
 * @description  영어,숫자로만 이루어 져있을 경우 true
 * <pre>
 *
 * </pre>
 * @param  {Char} arguments[0] 제거할문자
 * @return {boolean} true/false
 * @author 손찬욱
 */
String.prototype.isEngNum = function() {
	return (/^[0-9a-zA-Z]+$/).test((this || "").remove(arguments[0])) ? true : false;
};

/**
 * @memberOf String
 * @description  한글로만 이루어 져있을 경우 true
 * <pre>
 *
 * </pre>
 * @param  {Char} arguments[0] 제거할문자
 * @return {boolean} true/false
 * @author 손찬욱
 */
String.prototype.isHan = function() {
	var tmpStr = this || "";
	tmpStr = tmpStr.remove(arguments[0]);
	for (var i = 0; i < tmpStr.length; i++) {
	    if (tmpStr.charCodeAt(i) <= 127)
	    	return false;
	}
	return true;    	
};

/**
 * @memberOf String
 * @description   특수문자로만 이루어 져있을 경우 true
 * <pre>
 *
 * </pre>
 * @param  {Char} arguments[0] 제거할문자
 * @return {boolean} true/false
 * @author 손찬욱
 */
String.prototype.IsSpecial = function() {
	
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * @memberOf String
 * @description trim처리함.
 * <pre>
 *     var str = " abcde "
 *     str = str.trim();
 * </pre>
 * 위의 예에서 str는 "abcde"가 된다.
 * @return {String} replaced String.
 * @author 손찬욱
 */    
String.prototype.trim = function() {
	return (this || "").replace( /^\s+|\s+$/g, "" );
};
/**
 * @memberOf String
 * @description  자바스크립트의 내장 객체인 String 객체에 lpad 메소드를 추가한다. lpad 메소드는
 *           스트링에 자릿수 만큼 '문자'를 왼쪽에 붙여준다.
 * <pre>
 *     var str = "1"
 *     str = str.lpad(3, '0');
 * 위의 예에서 str는 "001"이 된다.
 * </pre>
 * @param  {Char} ch 바뀌어질 새로운 문자 
 * @param  {String} lenght 바뀌어질 새로운 스트링
 * @return {String} replaced String.
 * @author 손찬욱
 */
String.prototype.lpad = function(ch, length) {
    if(isNaN(length)) return this;
    var dataLength = this.length;
    var data = this;
    if(length>dataLength) 
    {
	     for(var i=0; i<(length-dataLength); i++) 
	     {
	     	data = ch + data;
	     }
    }
    return data;
};

 /**
 * @memberOf String
 * @description  자바스크립트의 내장 객체인 String 객체에 lpad 메소드를 추가한다. lpad 메소드는
 *           스트링에 자릿수 만큼 '문자'를 오른쪽에 붙여준다.
 * <pre>
 *     var str = "1"
 *     str = str.rpad(3, '0');
 * 위의 예에서 str는 "100"이 된다.
 * </pre>
 * @param  {Char} ch 바뀌어질 새로운 문자 
 * @param  {String} lenght 바뀌어질 새로운 스트링
 * @return {String} replaced String.
 * @author 손찬욱
 */
String.prototype.rpad = function(ch, length) {
    if(isNaN(length)) return this;
    var dataLength = this.length;
    var data = this;
    if(length>dataLength) 
    {
	     for(var i=0; i<(length-dataLength); i++) 
	     {
	     	data = data + ch;
	     }
    }
    return data;
};

/**
 * @memberOf String
 * @description  자바스크립트의 내장 객체인 String 객체에 insert 메소드를 추가한다. insert 메소드는 스트링의 특정 영역에
 *           주어진 스트링을 삽입한다.
 * <pre>
 *     var str = "abcde"
 *     str = str.insert(3, "xyz");
 * </pre>
 * 위의 예에서 str는 "abcxyzde"가 된다.
 * @param  {String} index 삽입할 위치. 해당 스트링의 index 바로 앞에 삽입된다. index는 0부터 시작.
 * @param  {String} str   삽입할 스트링.
 * @return {String} inserted String.
 * @author 임재현, 손찬욱 수정
 */
String.prototype.insert = function(index, str) {
	if(isNaN(index)) return this;
	if(index > this.length) return this;
	return this.substring(0, index) + str + this.substring(index);
};

/**
 * @memberOf String
 * @description 특정문자지우기
 * <pre>
 *     var str = "abcdbef"
 *     var rev = str.remove('b');
 * </pre>
 * 위의 예에서 rev는 acdef이 된다.
 * @return {String} 문자가 제거된 String
 * @author 손찬욱
 */  
String.prototype.remove = function(ch) {
	ch = ch || "";
	if(ch.trim().length != 1) return this; 
	var tmpStr1 = this || "";
	var tmpStr2 = "";
	for(var i=0; i<tmpStr1.length; i++) {
		if(tmpStr1.charAt(i) != ch ) {
			tmpStr2 += tmpStr1.charAt(i);
		}
	}
	return tmpStr2;
};

/**
 * @memberOf String
 * @description 역문자 얻기
 * <pre>
 *     var str = "abcdef"
 *     var rev = str.reverse();
 * </pre>
 * 위의 예에서 rev는 fedcba이 된다.
 * @return {String} 반대로 반환.
 */  
String.prototype.reverse = function() {
    var s = "";
    var i = this.length;
    while (i>0) {
        s += this.substring(i-1,i);
        i--;
    }
    return s;
};

/**
 * @memberOf String
 * @description   자바스크립트의 내장 객체인 String 객체에 replaceAll 메소드를 추가한다.
 * <pre>
 *   var str = "abcde & fghi"
 *   str = str.replaceAll("&", "and");
 * 위의 예에서 str는 "abcde and fghi"가 된다.
 * </pre>
 * @param  {String} old 문자열
 * @param  {String} new 문자열
 * @return {String} trimed String.
 */
String.prototype.replaceAll = function(matchStr, newStr) {
	var result = this;
	if(matchStr=="") return result;
	
	while(result.indexOf(matchStr)!=-1) {
		result = result.replace(matchStr, newStr);
	}
    return result;
}


/**
* @memberOf String
* @description byte 길이 반환
* <pre>
*     var str = "한글123"
*     var cnt = str.getByte();
* </pre>
* 위의 예에서 cnt는 7이 된다.
* @return {Int} Byte 길이
* @author 손찬욱
*/   
String.prototype.getByte = function() {
	var cnt = 0;
	for (var i = 0; i < this.length; i++) {
	    if (this.charCodeAt(i) > 127)
		cnt += 2;
	    else
		cnt++;
	}
	return cnt;
};

/**
 * @memberOf String
 * @description   앞부분과 같은지 검색
 * <pre>
 *     var str = "teststring";
 *     var isEqual = str.startWith("test") // true
 * </pre>
 * @return {Boolean} 중복여부
 * @author 손찬욱
 */
String.prototype.startWith = function(str) {
	str = str || "";
	var tmpStr = this || "";
	if(str.length <= tmpStr.length) {
		if(tmpStr.substring(0, str.length) == str) return true;
		else return false;
	} 
	return false;
};

/**
 * @memberOf String
 * @description   뒷부분과 같은지 검색
 * <pre>
 *     var str = "teststring";
 *     var isEqual = str.endWith("string") // true
 * </pre>
 * @return {Boolean} 중복여부
 * @author 손찬욱
 */
String.prototype.endWith = function(str) {
	str = str || "";
	var tmpStr = this || "";
	if(str.length <= tmpStr.length) {
		if(tmpStr.substring(tmpStr.length-str.length) == str) return true;
		else return false;
	} 
	return false;
};

/**
 * @memberOf String
 * @description   대소문자 구분없이 같은지 확인
 * <pre>
 *     var str1 = "teststring";
 *     var str2 = "TestString";
 *     
 *     str1.equalsIgnoreCase(str2); // true
 * </pre>
 * @return {Boolean} 동일 여부
 * @author 손찬욱
 */
String.prototype.equalsIgnoreCase = function(str) {
	str = str || "";
	var tmpStr = this || "";
	
	str = str.toUpperCase();
	tmpStr = tmpStr.toUpperCase();
	if( str == tmpStr ) return true;
	else return false;
};

/**
 * @memberOf String
 * @description   꺽쇠가 포함된 문자열을 &lt,&gt로 바꾼다.
 * <pre>
 *     var str = "<html>";
 *     str = str.XssEncoding();
 *    위의 예에서 str은 &ltthtml&gt 로 바뀐다.
 *    XSS 방지 모듈 Encoding
 * </pre>
 * @return {String} 변경된 문자
 * @author 손찬욱
 */
String.prototype.XssEncoding = function()
{
	var str = this || "";
	return str.replaceAll("&", "&#38;")
			.replaceAll("<", "&lt;")
			.replaceAll(">", "&gt;")
			.replaceAll("\\(", "&#40;")
			.replaceAll("\\)", "&#41;")
			.replace(/"/g, "&#34;")
			.replace(/'/g, "&#39;");
};

/**
 * @memberOf String
 * @description   &lt,&gt가 포함된 문자열을 꺽쇠로 바꾼다.
 * <pre>
 *     var str = "<thtml>";
 *     str = str.XssDecoding();
 *    위의 예에서 str은 <html> 로 바뀐다.
 *    XSS 방지 모듈 Decoding
 * </pre>
 * @return {String} 변경된 문자
 * @author 손찬욱
 */
String.prototype.XssDecoding = function()
{
	var str = this || "";
	return str.replaceAll("&lt;", "<")
			.replaceAll("&gt;", ">")
			.replaceAll("&#40;", "(")
			.replaceAll("&#41;", ")")
			.replaceAll("&#38;", "&")
			.replace("&#34;", /"/g)
			.replace("&#39;", /'/g);
};


/**
 * @memberOf String
 * @description   숫자형 문자영을 한글표기로 변경
 * <pre>
 *     var str = "109000000.0009002";
 *     str = str.toHan(); // str은 "일억구백만.영영영구영영이"
 * </pre>
 * @return {String} 변경된 문자
 * @author 손찬욱
 */
String.prototype.toHan = function() {
	if(isNaN(this)) {
		return this;
	}
	var coreFnc = function(amt, isDot) {
		var tmpamt = "";
		if (isDot == false) { // 정수처리
			if (amt.indexOf('.') != -1) {
				amt = amt.substring(0, amt.indexOf('.'));
			}
			if (amt.length > 3)
				amt = "000000000000" + amt;

			var j = 0;
			for ( var i = amt.length; i > 0; i--) {
				j++;
				if (amt.substring(i - 1, i) != "0") {
					if (j % 4 == 2)
						tmpamt = "십" + tmpamt;
					if (j % 4 == 3)
						tmpamt = "백" + tmpamt;
					if (j > 1 && (j % 4) == 0)
						tmpamt = "천" + tmpamt;
				}
				if (amt.length > 4) {
					if (j == 5
							&& parseInt(amt.substring(amt.length - 8,
									amt.length - 4), 10) > 0)
						tmpamt = "만" + tmpamt;
					if (j == 9
							&& parseInt(amt.substring(amt.length - 12,
									amt.length - 8), 10) > 0)
						tmpamt = "억" + tmpamt;
					if (j == 13
							&& parseInt(amt.substring(amt.length - 16,
									amt.length - 12), 10) > 0)
						tmpamt = "조" + tmpamt;
				}
				if (amt.substring(i - 1, i) == "1")
					tmpamt = "일" + tmpamt;
				if (amt.substring(i - 1, i) == "2")
					tmpamt = "이" + tmpamt;
				if (amt.substring(i - 1, i) == "3")
					tmpamt = "삼" + tmpamt;
				if (amt.substring(i - 1, i) == "4")
					tmpamt = "사" + tmpamt;
				if (amt.substring(i - 1, i) == "5")
					tmpamt = "오" + tmpamt;
				if (amt.substring(i - 1, i) == "6")
					tmpamt = "육" + tmpamt;
				if (amt.substring(i - 1, i) == "7")
					tmpamt = "칠" + tmpamt;
				if (amt.substring(i - 1, i) == "8")
					tmpamt = "팔" + tmpamt;
				if (amt.substring(i - 1, i) == "9")
					tmpamt = "구" + tmpamt;
			}
		} else { // 소수점 처리
			if (amt.indexOf('.') != -1) {
				amt = amt.substring(amt.indexOf('.') + 1);
			}
			var nonZeroAmt = "";
			j = 0;
			for (j = amt.length; j > 0; j--) {
				nonZeroAmt = amt.substring(j - 1, j);
				if (nonZeroAmt != "0")
					break;
			}
			amt = amt.substring(0, j);

			for (i = amt.length; i > 0; i--) {
				if (amt.substring(i - 1, i) == "0")
					tmpamt = "영" + tmpamt;
				if (amt.substring(i - 1, i) == "1")
					tmpamt = "일" + tmpamt;
				if (amt.substring(i - 1, i) == "2")
					tmpamt = "이" + tmpamt;
				if (amt.substring(i - 1, i) == "3")
					tmpamt = "삼" + tmpamt;
				if (amt.substring(i - 1, i) == "4")
					tmpamt = "사" + tmpamt;
				if (amt.substring(i - 1, i) == "5")
					tmpamt = "오" + tmpamt;
				if (amt.substring(i - 1, i) == "6")
					tmpamt = "육" + tmpamt;
				if (amt.substring(i - 1, i) == "7")
					tmpamt = "칠" + tmpamt;
				if (amt.substring(i - 1, i) == "8")
					tmpamt = "팔" + tmpamt;
				if (amt.substring(i - 1, i) == "9")
					tmpamt = "구" + tmpamt;
			}
			tmpamt = "." + tmpamt;
		}
		return tmpamt;
	};
	
	// 1. 정수부분 처리
	var tmpamt = coreFnc(this, false);
	// 2. 소수부분 처리
	if(this.indexOf('.') != -1) {
       tmpamt += coreFnc(this, true);
	}
	return tmpamt;
};

/*****************************************************************************/
/*------------------------- Array 확장 관련 함수 시작 ----------------------*/
/*****************************************************************************/	
/**
 * javascript Array 
 * @name Array
 * @constructor
*/
/**
 * @memberOf Array
 * @description 존재여부 반환
 * <pre>
 *     var result = new Array().isContain("김");
 * </pre>
 * @param  {String} element 존재여부를 확인할 객체
 * @return {boolean} 존재여부
 * @author  손찬욱
 */
Array.prototype.isContain = function (element)   {
    for (var i = 0; i < this.length; i++)   {
        if (this[i] == element)      {
             return true;
        }
    }
    return false;
};


/**
 * @memberOf Array
 * @description 중복된 원소 삭제
 * <pre>
 *     var result = new Array().rmvDuplicates();
 * </pre>
 * @param  {Function} 중복여부를 판별한 func포인터
 * @return {Array} 중복된 원소가 삭제된 array 객체
 * @author  손찬욱
 */      
Array.prototype.rmvDuplicates = function (compFunc) {
    if(compFunc == null) {
        compFunc = function(a,b){ 
            if(a == b) return true; 
            return false;
        };
    }
    if(this.length == 0) return this;
    
    var result=[];
    var lastValue=this[0];
    result[result.length] = lastValue;
    
    for (var i=1 ; i<this.length; i++)    {
        var curValue=this[i];
        if (  !compFunc(curValue,lastValue) )        {
            result[result.length] = curValue;
        }
        lastValue=curValue;
    }
    this.length = result.length;
    
    for(var i=0; i<result.length ;i++)  {
        this[i] = result[i];
    }
    return this;    
};